package com.jch.dm4_promise.examples;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class FTPClientUtil implements FTPUploader {

    final FTPClient ftp = new FTPClient();
    final Map<String,Boolean> dirCreateMap = new HashMap<>();

//    private FTPClientUtil(){
//    }
//
//    public static Future<FTPClientUtil> newInstance(final String ftpServer,final String username,final String password){
//        Callable<FTPClientUtil> callable = new Callable<FTPClientUtil>() {
//            @Override
//            public FTPClientUtil call() throws Exception {
//                FTPClientUtil self = new FTPClientUtil();
//                self.init(ftpServer,username,password,null);
//                return self;
//            }
//        };
//        final FutureTask<FTPClientUtil> task = new FutureTask<>(callable);
//        new Thread(task).start();
//        return task;
//    }

    public void init(String ftpServer,String username,String password,String serverDir) throws Exception{
        FTPClientConfig config = new FTPClientConfig();
        ftp.configure(config);
        int reply;
        ftp.connect(ftpServer);
        System.out.println(ftp.getReplyString());
        reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)){
            ftp.disconnect();
            throw new RuntimeException("FTP server refused connection.");
        }
        boolean isOK = ftp.login(username,password);
        if (isOK){
            System.out.println(ftp.getReplyString());
        }else {
            throw new RuntimeException("Failed to login." + ftp.getReplyString());
        }
        reply = ftp.cwd(serverDir);
        if (!FTPReply.isPositiveCompletion(reply)){
            ftp.disconnect();
            throw new RuntimeException("Failed to change working directory.reply:" + reply);
        }else{
            System.out.println(ftp.getReplyString());
        }
        ftp.setFileType(FTP.ASCII_FILE_TYPE);
    }

    @Override
    public void upload(File file) throws Exception {
        InputStream dataIn = new BufferedInputStream(new FileInputStream(file),1024*8);
        boolean isOK;
        String dirName = file.getParentFile().getName();
        String fileName = dirName + '/' + file.getName();
        ByteArrayInputStream checkFileInputStream = new ByteArrayInputStream("".getBytes());
        try{
            if (!dirCreateMap.containsKey(dirName)){
                ftp.makeDirectory(dirName);
                dirCreateMap.put(dirName,null);
            }
            try{
                isOK = ftp.storeFile(fileName,dataIn);
            }catch(IOException e){
                throw new RuntimeException("Failed to upload " + file,e);
            }
            if (isOK){
                ftp.storeFile(fileName + ".c",checkFileInputStream);
            }else{
                throw new RuntimeException("Failed to upload " + file + ",reply:"+ftp.getReplyString());
            }
        }finally{
            dataIn.close();
        }
    }

    @Override
    public void disconnect() {
        if (ftp.isConnected()){
            try{
                ftp.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
